"""
螺纹钢短周期预测策略
基于机器学习的螺纹钢短期价格预测策略，整合了多种技术指标和优化算法
"""

import numpy as np
import pandas as pd
from typing import Dict, Any, Optional
from datetime import datetime, timedelta
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_squared_error

try:
    from ..base_strategy import BaseStrategy, TradingSignal, SignalType
except ImportError:
    # For direct script execution
    import sys
    import os
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    from base_strategy import BaseStrategy, TradingSignal, SignalType
from tqsdk.ta import MA, RSI, ATR
from tqsdk.tafunc import ema


class RBShortTermPredictStrategy(BaseStrategy):
    """
    螺纹钢短周期预测策略
    
    专门针对螺纹钢期货的短期预测策略，使用机器学习模型
    结合技术指标进行5-15分钟级别的交易决策
    """
    
    def on_initialize(self) -> None:
        """策略初始化"""
        # 策略参数
        self.lookback_window = self.config.get('lookback_window', 60)  # 减少回溯窗口
        self.prediction_horizon = self.config.get('prediction_horizon', 3)  # 缩短预测周期
        self.stop_loss_pct = self.config.get('stop_loss_pct', 0.008)  # 收紧止损
        self.take_profit_pct = self.config.get('take_profit_pct', 0.016)  # 收紧止盈
        self.retrain_interval = self.config.get('retrain_interval', 10)  # 更频繁重训练
        self.prediction_threshold = self.config.get('prediction_threshold', 0.0008)  # 降低阈值
        self.confidence_threshold = self.config.get('confidence_threshold', 0.6)
        
        # 模型参数
        self.use_ensemble = self.config.get('use_ensemble', True)
        self.model_type = self.config.get('model_type', 'random_forest')  # 'linear', 'random_forest'
        
        # 机器学习模型
        if self.model_type == 'random_forest':
            self.model = RandomForestRegressor(
                n_estimators=50,
                max_depth=10,
                random_state=42,
                n_jobs=-1
            )
        else:
            self.model = LinearRegression()
            
        self.scaler = StandardScaler()
        self.is_model_trained = False
        self.model_score = 0.0
        
        # 交易状态
        self.stop_loss_price = 0.0
        self.take_profit_price = 0.0
        self.trailing_stop_price = 0.0
        self.last_trade_time = None
        self.last_train_time = None
        
        # 数据缓存
        self.kline_data_5m = pd.DataFrame()
        self.kline_data_15m = pd.DataFrame()
        
        # 性能统计
        self.prediction_accuracy = []
        self.recent_predictions = []
        
        self.logger.info(f"螺纹钢短周期预测策略初始化完成: {self.name}")
    
    def on_bar(self, bar_data: Dict[str, Any]) -> None:
        """K线数据回调"""
        # 更新K线数据
        self._update_kline_data()
        
        # 检查数据是否足够
        if (len(self.kline_data_5m) < self.lookback_window + self.prediction_horizon or
            len(self.kline_data_15m) < 50):
            return
        
        # 检查是否需要训练或重新训练模型
        if not self.is_model_trained or self._should_retrain():
            if self._train_model():
                self.last_train_time = datetime.now()
                self.logger.info(f"模型训练完成，评分: {self.model_score:.4f}")
            else:
                self.logger.warning("模型训练失败")
                return
        
        # 执行交易逻辑
        self._execute_trading_logic()
    
    def on_tick(self, tick_data: Dict[str, Any]) -> None:
        """Tick数据回调"""
        # 实时更新价格用于止损止盈检查
        if self.position != 0:
            current_price = tick_data.get('last_price', 0)
            if current_price > 0:
                self._update_trailing_stop(current_price)
                self._check_stop_loss_take_profit(current_price)
    
    def on_signal(self) -> Optional[TradingSignal]:
        """信号生成回调"""
        return None
    
    def on_position_sizing(self, signal: TradingSignal) -> int:
        """仓位计算回调"""
        # 根据模型置信度调整仓位
        base_size = 1
        confidence = signal.metadata.get('confidence', 0.5)
        
        if confidence > 0.8:
            return base_size * 2  # 高置信度加倍仓位
        elif confidence > 0.6:
            return base_size
        else:
            return 0  # 低置信度不交易
    
    def _update_kline_data(self) -> None:
        """更新K线数据"""
        if self.data_manager:
            # 获取5分钟和15分钟K线数据
            self.kline_data_5m = self.data_manager.get_kline_data(
                self.symbol, 5*60, max(300, self.lookback_window * 2)
            )
            self.kline_data_15m = self.data_manager.get_kline_data(
                self.symbol, 15*60, 200
            )
    
    def _should_retrain(self) -> bool:
        """判断是否需要重新训练模型"""
        if self.last_train_time is None:
            return True
        
        # 基于时间的重训练
        hours_since_train = (datetime.now() - self.last_train_time).total_seconds() / 3600
        if hours_since_train >= self.retrain_interval:
            return True
        
        # 基于预测准确率的重训练
        if len(self.prediction_accuracy) >= 10:
            recent_accuracy = np.mean(self.prediction_accuracy[-10:])
            if recent_accuracy < 0.5:  # 准确率低于50%
                return True
        
        return False
    
    def _train_model(self) -> bool:
        """训练机器学习模型"""
        try:
            if len(self.kline_data_5m) < self.lookback_window + self.prediction_horizon:
                return False
            
            # 准备训练数据
            X, y = self._prepare_training_data()
            
            if len(X) == 0 or len(y) == 0:
                return False
            
            # 时间序列交叉验证
            tscv = TimeSeriesSplit(n_splits=3)
            scores = []
            
            for train_idx, val_idx in tscv.split(X):
                X_train, X_val = X[train_idx], X[val_idx]
                y_train, y_val = y[train_idx], y[val_idx]
                
                # 标准化特征
                scaler = StandardScaler()
                X_train_scaled = scaler.fit_transform(X_train)
                X_val_scaled = scaler.transform(X_val)
                
                # 训练模型
                if self.model_type == 'random_forest':
                    model = RandomForestRegressor(
                        n_estimators=50,
                        max_depth=10,
                        random_state=42,
                        n_jobs=-1
                    )
                else:
                    model = LinearRegression()
                
                model.fit(X_train_scaled, y_train)
                
                # 验证
                y_pred = model.predict(X_val_scaled)
                score = 1 - mean_squared_error(y_val, y_pred)
                scores.append(score)
            
            # 使用全部数据训练最终模型
            X_scaled = self.scaler.fit_transform(X)
            self.model.fit(X_scaled, y)
            self.is_model_trained = True
            self.model_score = np.mean(scores)
            
            self.logger.info(f"模型训练完成，交叉验证评分: {self.model_score:.4f}, 训练样本数: {len(X)}")
            return True
            
        except Exception as e:
            self.logger.error(f"模型训练失败: {e}")
            return False
    
    def _prepare_training_data(self) -> tuple:
        """准备训练数据"""
        features_list = []
        targets_list = []
        
        for i in range(self.lookback_window, len(self.kline_data_5m) - self.prediction_horizon):
            # 获取历史数据片段
            data_slice_5m = self.kline_data_5m.iloc[i-self.lookback_window:i].copy()
            
            # 获取对应的15分钟数据
            current_time = self.kline_data_5m.iloc[i]['datetime']
            data_slice_15m = self._get_15m_data_slice(current_time)
            
            # 提取特征
            features = self._extract_enhanced_features(data_slice_5m, data_slice_15m)
            if features is not None:
                features_list.append(features)
                
                # 定义目标变量：未来价格变化率
                future_price = self.kline_data_5m['close'].iloc[i + self.prediction_horizon - 1]
                current_price = self.kline_data_5m['close'].iloc[i - 1]
                target = (future_price - current_price) / current_price
                targets_list.append(target)
        
        return np.array(features_list), np.array(targets_list)
    
    def _get_15m_data_slice(self, current_time: pd.Timestamp) -> pd.DataFrame:
        """获取对应时间的15分钟数据片段"""
        try:
            # 找到最接近的15分钟数据
            time_diff = np.abs(self.kline_data_15m['datetime'] - current_time)
            closest_idx = time_diff.idxmin()
            
            # 返回最近20根15分钟K线
            start_idx = max(0, closest_idx - 19)
            return self.kline_data_15m.iloc[start_idx:closest_idx+1].copy()
        except:
            return pd.DataFrame()
    
    def _extract_enhanced_features(self, data_5m: pd.DataFrame, data_15m: pd.DataFrame) -> Optional[np.ndarray]:
        """提取增强特征"""
        try:
            features = []
            
            # 5分钟数据特征
            features.extend(self._extract_price_features(data_5m))
            features.extend(self._extract_volume_features(data_5m))
            features.extend(self._extract_technical_features(data_5m))
            
            # 15分钟数据特征（趋势确认）
            if not data_15m.empty:
                features.extend(self._extract_trend_features(data_15m))
            else:
                features.extend([0] * 10)  # 填充默认值
            
            # 市场微观结构特征
            features.extend(self._extract_microstructure_features(data_5m))
            
            # 波动率特征
            features.extend(self._extract_volatility_features(data_5m))
            
            return np.array(features)
            
        except Exception as e:
            self.logger.error(f"特征提取失败: {e}")
            return None
    
    def _extract_price_features(self, data: pd.DataFrame) -> list:
        """提取价格特征"""
        features = []
        
        # 价格动量特征
        for period in [3, 5, 10, 15]:
            if len(data) > period:
                momentum = data['close'].pct_change(period).fillna(0).iloc[-1]
                features.append(momentum)
            else:
                features.append(0)
        
        # 价格位置特征
        for period in [10, 20, 30]:
            if len(data) >= period:
                high_max = data['high'].rolling(period).max().iloc[-1]
                low_min = data['low'].rolling(period).min().iloc[-1]
                if high_max != low_min:
                    price_position = (data['close'].iloc[-1] - low_min) / (high_max - low_min)
                else:
                    price_position = 0.5
                features.append(price_position)
            else:
                features.append(0.5)
        
        # 价格差值特征
        features.append((data['close'].iloc[-1] - data['open'].iloc[-1]) / data['open'].iloc[-1])
        features.append((data['high'].iloc[-1] - data['low'].iloc[-1]) / data['close'].iloc[-1])
        
        return features
    
    def _extract_volume_features(self, data: pd.DataFrame) -> list:
        """提取成交量特征"""
        features = []
        
        # 成交量动量
        for period in [5, 10, 20]:
            if len(data) >= period:
                vol_ma = data['volume'].rolling(period).mean().iloc[-1]
                if vol_ma > 0:
                    vol_ratio = data['volume'].iloc[-1] / vol_ma
                else:
                    vol_ratio = 1
                features.append(vol_ratio)
            else:
                features.append(1)
        
        # 价量关系
        if len(data) >= 5:
            price_change = data['close'].pct_change(5).iloc[-1]
            volume_change = data['volume'].pct_change(5).iloc[-1]
            if abs(volume_change) > 1e-6:
                price_volume_corr = price_change / volume_change
            else:
                price_volume_corr = 0
            features.append(price_volume_corr)
        else:
            features.append(0)
        
        return features
    
    def _extract_technical_features(self, data: pd.DataFrame) -> list:
        """提取技术指标特征"""
        features = []
        
        # RSI特征
        for period in [5, 10, 14]:
            try:
                rsi_val = RSI(data, period).rsi.iloc[-1]
                if pd.isna(rsi_val):
                    rsi_val = 50
                features.append(rsi_val / 100)  # 归一化到0-1
            except:
                features.append(0.5)
        
        # 移动平均线特征
        for period in [5, 10, 20]:
            try:
                ma_val = MA(data, period).ma.iloc[-1]
                if pd.isna(ma_val) or ma_val == 0:
                    ma_ratio = 1
                else:
                    ma_ratio = data['close'].iloc[-1] / ma_val
                features.append(ma_ratio)
            except:
                features.append(1)
        
        # MACD特征
        try:
            ema_12 = ema(data['close'].values, 12)
            ema_26 = ema(data['close'].values, 26)
            dif = ema_12 - ema_26
            dea = ema(dif, 9)
            macd_hist = dif - dea
            
            features.append(dif[-1] / data['close'].iloc[-1])  # 归一化
            features.append(dea[-1] / data['close'].iloc[-1])
            features.append(macd_hist[-1] / data['close'].iloc[-1])
        except:
            features.extend([0, 0, 0])
        
        return features
    
    def _extract_trend_features(self, data_15m: pd.DataFrame) -> list:
        """提取趋势特征（基于15分钟数据）"""
        features = []
        
        # 长期趋势
        for period in [10, 20]:
            try:
                ma_val = MA(data_15m, period).ma.iloc[-1]
                if pd.isna(ma_val) or ma_val == 0:
                    trend_ratio = 1
                else:
                    trend_ratio = data_15m['close'].iloc[-1] / ma_val
                features.append(trend_ratio)
            except:
                features.append(1)
        
        # 趋势强度
        if len(data_15m) >= 10:
            price_changes = data_15m['close'].pct_change().dropna()
            trend_strength = np.mean(price_changes[-10:])
            features.append(trend_strength)
        else:
            features.append(0)
        
        # ATR相对值
        try:
            atr_val = ATR(data_15m, 14).atr.iloc[-1]
            atr_ratio = atr_val / data_15m['close'].iloc[-1]
            features.append(atr_ratio)
        except:
            features.append(0.01)
        
        # 填充剩余特征
        features.extend([0] * (10 - len(features)))
        
        return features[:10]
    
    def _extract_microstructure_features(self, data: pd.DataFrame) -> list:
        """提取市场微观结构特征"""
        features = []
        
        # 买卖压力指标
        if len(data) >= 5:
            # 上影线比例
            upper_shadow = (data['high'] - np.maximum(data['open'], data['close'])) / (data['high'] - data['low'] + 1e-8)
            # 下影线比例
            lower_shadow = (np.minimum(data['open'], data['close']) - data['low']) / (data['high'] - data['low'] + 1e-8)
            
            features.append(upper_shadow.mean())
            features.append(lower_shadow.mean())
            
            # 实体比例
            body_ratio = np.abs(data['close'] - data['open']) / (data['high'] - data['low'] + 1e-8)
            features.append(body_ratio.mean())
        else:
            features.extend([0.3, 0.3, 0.4])
        
        return features
    
    def _extract_volatility_features(self, data: pd.DataFrame) -> list:
        """提取波动率特征"""
        features = []
        
        # 历史波动率
        returns = data['close'].pct_change().dropna()
        for period in [5, 10, 20]:
            if len(returns) >= period:
                vol = returns.rolling(period).std().iloc[-1]
                features.append(vol if not pd.isna(vol) else 0)
            else:
                features.append(0)
        
        # 波动率比率
        if len(returns) >= 20:
            short_vol = returns.rolling(5).std().iloc[-1]
            long_vol = returns.rolling(20).std().iloc[-1]
            if long_vol > 0:
                vol_ratio = short_vol / long_vol
            else:
                vol_ratio = 1
            features.append(vol_ratio)
        else:
            features.append(1)
        
        return features
    
    def _predict_with_confidence(self) -> tuple:
        """预测并返回置信度"""
        try:
            if not self.is_model_trained:
                return None, 0.0
            
            # 提取当前特征
            data_slice_5m = self.kline_data_5m.iloc[-self.lookback_window:].copy()
            current_time = self.kline_data_5m.iloc[-1]['datetime']
            data_slice_15m = self._get_15m_data_slice(current_time)
            
            features = self._extract_enhanced_features(data_slice_5m, data_slice_15m)
            if features is None:
                return None, 0.0
            
            # 标准化特征
            features_scaled = self.scaler.transform(features.reshape(1, -1))
            
            # 预测
            prediction = self.model.predict(features_scaled)[0]
            
            # 计算置信度
            confidence = self._calculate_confidence(features, prediction)
            
            return prediction, confidence
            
        except Exception as e:
            self.logger.error(f"预测失败: {e}")
            return None, 0.0
    
    def _calculate_confidence(self, features: np.ndarray, prediction: float) -> float:
        """计算预测置信度"""
        try:
            # 基于模型评分的基础置信度
            base_confidence = max(0.1, min(0.9, self.model_score))
            
            # 基于预测强度的调整
            prediction_strength = min(1.0, abs(prediction) / 0.01)  # 预测强度
            
            # 基于特征一致性的调整
            feature_consistency = self._calculate_feature_consistency(features)
            
            # 综合置信度
            confidence = base_confidence * 0.4 + prediction_strength * 0.3 + feature_consistency * 0.3
            
            return max(0.1, min(0.95, confidence))
            
        except:
            return 0.5
    
    def _calculate_feature_consistency(self, features: np.ndarray) -> float:
        """计算特征一致性"""
        try:
            # 简单的特征一致性检查
            # 检查价格动量和技术指标的一致性
            price_momentum = np.mean(features[:4])  # 前4个是价格动量特征
            technical_signals = np.mean(features[10:16])  # 技术指标特征
            
            # 计算一致性得分
            consistency = 1 - abs(price_momentum - technical_signals)
            return max(0.1, min(1.0, consistency))
            
        except:
            return 0.5
    
    def _execute_trading_logic(self) -> None:
        """执行交易逻辑"""
        try:
            # 获取预测结果和置信度
            prediction, confidence = self._predict_with_confidence()
            if prediction is None or confidence < self.confidence_threshold:
                return
            
            current_price = self.kline_data_5m['close'].iloc[-1]
            current_time = datetime.now()
            
            # 控制交易频率
            if (self.last_trade_time and 
                (current_time - self.last_trade_time).total_seconds() < 180):  # 3分钟间隔
                return
            
            # 计算ATR用于动态止损止盈
            atr_val = self._calculate_atr()
            
            if self.position == 0:  # 无持仓
                signal_generated = False
                
                if prediction > self.prediction_threshold:
                    # 做多信号
                    signal = TradingSignal(
                        strategy_name=self.name,
                        symbol=self.symbol,
                        signal_type=SignalType.LONG,
                        volume=1,
                        price=current_price,
                        timestamp=current_time,
                        confidence=confidence,
                        metadata={
                            'prediction': prediction,
                            'confidence': confidence,
                            'model_score': self.model_score
                        }
                    )
                    
                    # 设置止损止盈
                    if atr_val > 0:
                        self.stop_loss_price = current_price - 1.5 * atr_val
                        self.take_profit_price = current_price + 2.5 * atr_val
                        self.trailing_stop_price = self.stop_loss_price
                    else:
                        self.stop_loss_price = current_price * (1 - self.stop_loss_pct)
                        self.take_profit_price = current_price * (1 + self.take_profit_pct)
                        self.trailing_stop_price = self.stop_loss_price
                    
                    signal_generated = True
                    
                elif prediction < -self.prediction_threshold:
                    # 做空信号
                    signal = TradingSignal(
                        strategy_name=self.name,
                        symbol=self.symbol,
                        signal_type=SignalType.SHORT,
                        volume=1,
                        price=current_price,
                        timestamp=current_time,
                        confidence=confidence,
                        metadata={
                            'prediction': prediction,
                            'confidence': confidence,
                            'model_score': self.model_score
                        }
                    )
                    
                    # 设置止损止盈
                    if atr_val > 0:
                        self.stop_loss_price = current_price + 1.5 * atr_val
                        self.take_profit_price = current_price - 2.5 * atr_val
                        self.trailing_stop_price = self.stop_loss_price
                    else:
                        self.stop_loss_price = current_price * (1 + self.stop_loss_pct)
                        self.take_profit_price = current_price * (1 - self.take_profit_pct)
                        self.trailing_stop_price = self.stop_loss_price
                    
                    signal_generated = True
                
                if signal_generated:
                    # 更新状态
                    self.position = 1 if signal.signal_type == SignalType.LONG else -1
                    self.entry_price = current_price
                    self.last_trade_time = current_time
                    
                    # 记录预测用于后续准确率计算
                    self.recent_predictions.append({
                        'prediction': prediction,
                        'actual_price': current_price,
                        'timestamp': current_time,
                        'position': self.position
                    })
                    
                    # 触发信号回调
                    if self.signal_callback:
                        self.signal_callback(signal)
                    
                    direction = "做多" if self.position > 0 else "做空"
                    self.logger.info(f"生成{direction}信号: 预测={prediction:.6f}, 置信度={confidence:.3f}, 价格={current_price}")
            
            else:  # 有持仓，检查是否需要平仓
                should_close = False
                close_reason = ""
                
                # 检查预测反转
                if ((self.position > 0 and prediction < -self.prediction_threshold * 0.5) or
                    (self.position < 0 and prediction > self.prediction_threshold * 0.5)):
                    should_close = True
                    close_reason = "预测反转"
                
                if should_close:
                    self._close_position(current_price, close_reason)
                    
        except Exception as e:
            self.logger.error(f"交易逻辑执行失败: {e}")
    
    def _update_trailing_stop(self, current_price: float) -> None:
        """更新移动止损"""
        if self.position > 0:  # 多头持仓
            # 价格上涨时提高止损价
            new_trailing_stop = current_price - (self.entry_price - self.trailing_stop_price)
            if new_trailing_stop > self.trailing_stop_price:
                self.trailing_stop_price = new_trailing_stop
        
        elif self.position < 0:  # 空头持仓
            # 价格下跌时降低止损价
            new_trailing_stop = current_price + (self.trailing_stop_price - self.entry_price)
            if new_trailing_stop < self.trailing_stop_price:
                self.trailing_stop_price = new_trailing_stop
    
    def _check_stop_loss_take_profit(self, current_price: float) -> None:
        """检查止损止盈"""
        should_close = False
        close_reason = ""
        
        if self.position > 0:  # 多头持仓
            if current_price <= self.trailing_stop_price:
                should_close = True
                close_reason = "多头移动止损"
            elif current_price >= self.take_profit_price:
                should_close = True
                close_reason = "多头止盈"
        
        elif self.position < 0:  # 空头持仓
            if current_price >= self.trailing_stop_price:
                should_close = True
                close_reason = "空头移动止损"
            elif current_price <= self.take_profit_price:
                should_close = True
                close_reason = "空头止盈"
        
        if should_close:
            self._close_position(current_price, close_reason)
    
    def _close_position(self, current_price: float, reason: str) -> None:
        """平仓"""
        signal = TradingSignal(
            strategy_name=self.name,
            symbol=self.symbol,
            signal_type=SignalType.CLOSE,
            volume=abs(self.position),
            price=current_price,
            timestamp=datetime.now(),
            confidence=1.0,
            metadata={'close_reason': reason}
        )
        
        # 记录交易
        pnl = self._calculate_pnl(current_price)
        self.trades.append({
            'entry_price': self.entry_price,
            'exit_price': current_price,
            'position': self.position,
            'pnl': pnl,
            'close_reason': reason,
            'timestamp': datetime.now()
        })
        
        # 更新预测准确率
        self._update_prediction_accuracy(current_price)
        
        # 重置状态
        self.position = 0
        self.entry_price = 0.0
        self.stop_loss_price = 0.0
        self.take_profit_price = 0.0
        self.trailing_stop_price = 0.0
        self.last_trade_time = datetime.now()
        
        # 触发信号回调
        if self.signal_callback:
            self.signal_callback(signal)
        
        self.logger.info(f"{reason}: 价格={current_price}, 盈亏={pnl:.2f}")
    
    def _update_prediction_accuracy(self, exit_price: float) -> None:
        """更新预测准确率"""
        try:
            if self.recent_predictions:
                last_pred = self.recent_predictions[-1]
                entry_price = last_pred['actual_price']
                prediction = last_pred['prediction']
                position = last_pred['position']
                
                # 计算实际价格变化
                actual_change = (exit_price - entry_price) / entry_price
                
                # 判断预测是否正确
                if position > 0:  # 多头
                    correct = (prediction > 0 and actual_change > 0) or (prediction <= 0 and actual_change <= 0)
                else:  # 空头
                    correct = (prediction < 0 and actual_change < 0) or (prediction >= 0 and actual_change >= 0)
                
                self.prediction_accuracy.append(1.0 if correct else 0.0)
                
                # 保持最近100次预测记录
                if len(self.prediction_accuracy) > 100:
                    self.prediction_accuracy = self.prediction_accuracy[-100:]
                
        except Exception as e:
            self.logger.error(f"预测准确率更新失败: {e}")
    
    def _calculate_pnl(self, exit_price: float) -> float:
        """计算盈亏"""
        if self.position > 0:
            return (exit_price - self.entry_price) * self.position
        elif self.position < 0:
            return (self.entry_price - exit_price) * abs(self.position)
        return 0.0
    
    def _calculate_atr(self, period: int = 14) -> float:
        """计算ATR"""
        try:
            if len(self.kline_data_5m) < period:
                return 0.0
            
            atr_indicator = ATR(self.kline_data_5m, period)
            atr_val = atr_indicator.atr.iloc[-1]
            
            return atr_val if not pd.isna(atr_val) else 0.0
            
        except Exception as e:
            self.logger.error(f"ATR计算失败: {e}")
            return 0.0
    
    def get_performance_metrics(self) -> Dict[str, Any]:
        """获取策略性能指标"""
        metrics = super().get_performance_metrics()
        
        # 添加策略特有指标
        if self.prediction_accuracy:
            metrics['prediction_accuracy'] = np.mean(self.prediction_accuracy)
            metrics['recent_accuracy'] = np.mean(self.prediction_accuracy[-20:]) if len(self.prediction_accuracy) >= 20 else 0
        else:
            metrics['prediction_accuracy'] = 0
            metrics['recent_accuracy'] = 0
        
        metrics['model_score'] = self.model_score
        metrics['model_type'] = self.model_type
        metrics['total_predictions'] = len(self.prediction_accuracy)
        
        return metrics